﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Kooboo.Commerce.Contexts.Orders;
using System.Text;
using System.IO;
using System.Net;

namespace Kooboo.Commerce.Payments.PayPal.Controllers
{
    public class PayPalServiceController : Controller
    {
        public ActionResult Return(Guid token)
        {
            //var orderToken = Services.Current.DataConext.Payment_Paypal_OrderTokens.Where(o => o.OrderTraceToken == token).FirstOrDefault();
            //if (orderToken != null && orderToken.ExecStatus == (byte)PaymentStatus.CREATED)
            //{
            //    orderToken.ExecStatus = (byte)PaymentStatus.COMPLETED;
            //    Services.Current.DataConext.SubmitChanges();

            //    var host = new ServiceHost();
            //    IOrder order = host.QueryOrders().Where(o => o.Id == orderToken.OrderID).FirstOrDefault();
            //    if (order != null && order.OrderStatus == OrderStatus.PaymentPending)
            //    {
            //        order.OrderStatus = OrderStatus.InProgress;
            //        host.Put(order);
            //    }
            //}

            return RedirectToAction("Index", "Order");

            //return View();
        }

        public ActionResult Cancel(String token)
        {
            return View();
        }

        private const String IPN_VALID = "VERIFIED";

        /// <summary>
        /// Instant Payment Notifications
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult IPN(Guid token)
        {

#if DEBUG
            RecordIPNMessage(token);
#endif
            //valid IPN message

            String strPayKey = Request.Form["pay_key"];
            String strStatus = Request.Form["status"];

            StringBuilder postData = new StringBuilder();
            foreach (var key in Request.Form.AllKeys)
            {
                if (postData.Length > 0)
                {
                    postData.Append("&");
                }
                postData.AppendFormat("{0}={1}", key, HttpUtility.UrlEncode(Request.Form[key]));
            }

            if (postData.Length > 0)
            {
                postData.Append("&cmd=_notify-validate");

                //valid IPN message
                var objWebRequest = (HttpWebRequest)HttpWebRequest.Create(IPNMessageVerifyURL);
                objWebRequest.Method = "POST";
                objWebRequest.ContentType = "application/x-www-form-urlencoded";
                var bytes = Encoding.UTF8.GetBytes(postData.ToString());
                objWebRequest.ContentLength = bytes.Length;
                var reqStream = objWebRequest.GetRequestStream();
                reqStream.Write(bytes, 0, bytes.Length);
                reqStream.Close();

                //read response
                String rspContent = String.Empty;
                var objResponse = objWebRequest.GetResponse();
                using (StreamReader reader = new StreamReader(objResponse.GetResponseStream()))
                {
                    rspContent = reader.ReadToEnd();
                }
                //check response content
                if (rspContent == IPN_VALID)
                {
                    PaymentStatus status = (PaymentStatus)Enum.Parse(typeof(PaymentStatus), strStatus, true);
                    if (status == PaymentStatus.COMPLETED)
                    {
                        var orderToken = Services.Current.DataConext.Payment_Paypal_OrderTokens
                            .Where(o => o.OrderTraceToken == token && o.PayKey == strPayKey).FirstOrDefault();
                        if (orderToken != null)
                        {
                            orderToken.ExecStatus = (byte)PaymentStatus.COMPLETED;
                            Services.Current.DataConext.SubmitChanges();

                            //Update Order payment status
                            var host = new ServiceHost();
                            IOrder order = host.QueryOrders().Where(o => o.Id == orderToken.OrderID).FirstOrDefault();
                            if (order != null && order.OrderStatus == OrderStatus.PaymentPending)
                            {
                                order.OrderStatus = OrderStatus.InProgress;
                                host.Put(order);
                            }
                        }
                    }
                }
            }

            return View();
        }

        /// <summary>
        /// save IPN message to file
        /// </summary>
        /// <param name="orderTraceToken"></param>
        private void RecordIPNMessage(Guid orderTraceToken)
        {
            StringBuilder builder = new StringBuilder();
            foreach (var item in this.Request.Form.AllKeys)
            {
                builder.AppendFormat("{0}={1}\r\n", item, Request.Form[item]);
            }
            String path = Server.MapPath("~/Log/Payment/Paypal/IPN_Record");
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            using (StreamWriter writer = new StreamWriter(Path.Combine(path, orderTraceToken.ToString("N"))))
            {
                writer.Write(builder.ToString());
            }
        }

        String strSandbox_IPNVerifyURL = "http://www.sandbox.paypal.com/cgi-bin/webscr";

        String strIPNVerifyURL = "https://www.sandbox.paypal.com/cgi-bin/webscr";

        private String IPNMessageVerifyURL
        {
            get
            {
                var setting = Services.FindSettings();
                if (setting.GoLive)
                {
                    return strIPNVerifyURL;
                }
                else
                {
                    return strSandbox_IPNVerifyURL;
                }
            }
        }
    }
}